import * as Socketio from 'socket.io';
import server from './server';
import logger from './logger';
import { config } from '../config';
import Auth from './auth';
import { roles } from '../config/roles';
import Message from '../model/message';
import { sel_by_receiver_and_isPosted, upd_by_id } from '../mapper/msgMapper';
import {Disconnect, ReadMsg} from '../socket/index';
// import {instance as RbmqProxy} from './rabbitmqProxy';
import { client as redis } from './redisProxy';

let clients_alive: Map<string, string> = new Map();

class SocketIoProxy {
  _instance: SocketIoProxy|null = null;
  server: Socketio.Server;
  static _instance: SocketIoProxy;
  constructor() {
    this.server = new Socketio.Server(server);
    logger.info('SocketIo server created!');
    //监听连接拉起事件
    this.server.on('connection', async (socket) => {
      // const {channel: rbmq} = await RbmqProxy;

      // setTimeout(()=>{
      //   logger.info(`测试: 5秒后postmsg`);
      //   rbmq.assertQueue("post-msg");
      //   rbmq.sendToQueue("post-msg", Buffer.from(
      //     JSON.stringify({
      //       "receiver": "ca31a22f-1eb0-423a-8fcc-6b75f6a1e7b0",
      //       "sender": "系统",
      //       "title": "商品价格变化",
      //       "content": "您收藏的道酝琵琶降价了，当前价格为980.00￥",
      //       "data": "{\"gid\":\"g1\"}",
      //       "type": "系统通知"
      //     })
      //   ))
      // },5000)

      const satoken: string = socket.handshake.headers[config.satoken['token-name']] as string;
      const {id: uid, role} = await Auth.decryptToken(satoken);
      logger.info(`${roles[role]}(${uid}) connected.`);
      // socket.id和uid映射需要放在redis或者内存中
      await redis.set(uid, socket.id);
      // clients_alive.set(uid, socket.id);
      socket.emit("response","Hello, I'm the Socket.io Server.");
  
      // 检查是否有因用户不在线等待推送的通知
      const unPosted: Message[] = await sel_by_receiver_and_isPosted({receiver: uid, isPosted: 0});
      if (unPosted) {
          unPosted.forEach(message=>{
              message.isPosted = 1;
              socket.emit("notice", message);
              logger.info(`[server]: ${JSON.stringify(message)}`);
              upd_by_id(message.id, {isPosted: 1});  //标记为已推送
          })
      }

      //监听连接断开事件
      const disconnect = Disconnect(this.server, socket);
      socket.on(disconnect.name, disconnect.handler);

      //监听读取消息事件
      const readmsg = ReadMsg(this.server, socket);
      socket.on(readmsg.name, readmsg.handler);
    });
  }

  static instance(){
    if(!this._instance){
      this._instance = new SocketIoProxy();
    }
    return this._instance;
  }
}

export async function init() {
  return SocketIoProxy.instance();
}

export const instance = SocketIoProxy.instance();

export const clients = clients_alive;

export default {
  init,
  instance: SocketIoProxy.instance(),
  clients : clients_alive
}
